package com.zhanghaijun.createCode.service;

import com.zhanghaijun.createCode.bean.Model;
import com.zhanghaijun.createCode.bean.Property;
import com.zhanghaijun.createCode.util.*;
import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.*;

/**
 * Created by zhanghaijun on 15/4/29.
 * 自动生成
 * javaBean service dao xml
 */
public class autoCreateBeanServiceDaoXmlService {

    private static String info_schma_table_name = "information_schema";
    private static String ip = "127.0.0.1";
    private static String port = "3306";
    private static String params = "useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull";
    private static String user = "root";
    private static String password = "";
    private static String tableName = "z_user";
    private static String localPackage = "com.enniu";
    private static String modelSchema = "51nb_monitor";
    private static String elementName = "enniu";
    private static String author = "zhanghaijun";
    private static String email = "zhanghaijun8755018@163.com";
    private static String searchProsStr = "id";
    private static String date = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date());
    private static String sqlSession ="sqlSessionCfRegion";

    /**
     * 自动生产javaBean dao xml
     *
     * @throws Exception
     */
    public static void autoCreateBeanServiceDaoXml() throws Exception {

        String url = "jdbc:mysql://" + ip + ":" + port + "/" + info_schma_table_name + "?" + params;
        Model model = buildModelInfo(url, tableName, modelSchema);
        List<String> packageNames = getPackageName(model);
        Configuration cfg = new Configuration();
        cfg.setSharedVariable("DataTypeAdapt", new DataTypeAdaptUtil());
        cfg.setSharedVariable("TableNameConvert", new TableNameConvertUtil());
        cfg.setSharedVariable("NameConvert", new NameConvertUtil());
        cfg.setClassForTemplateLoading(autoCreateBeanServiceDaoXmlService.class, File.separator + "curdTemplates");

        Map root = new HashMap();
        root.put("model", model);
        root.put("author", author);
        root.put("date", date);
        root.put("email", email);
        root.put("importPackages", packageNames);
        root.put("localPackage", localPackage);
        root.put("tableName", tableName);
        root.put("elementName", elementName);
        root.put("modelSchema", modelSchema);
        root.put("sqlSession",sqlSession);

        String[] searchProsArray = (searchProsStr==null?"":searchProsStr).split(",");
        root.put("searchPros", getSearchPros(model, Arrays.asList(searchProsArray)));//搜索条件
        putConsts(root, model);
        createBean(cfg, root);
        createDao(cfg, root);
        createService(cfg, root);
        createController(cfg, root);
        createXML(cfg, root);
        createVM(cfg,root);
    }

    /**
     * Mysql表模型 映射成 Java模型
     * @param url
     * @param tableName
     * @param modelSchema
     * @return
     */
    private static Model buildModelInfo(String url, String tableName, String modelSchema) throws Exception {
        Model model = new Model();
        model.setName(TableNameConvertUtil.convert4ClassName(tableName));
        Connection connection = DriverManager.getConnection(url, user, password);
        String sqlStr = "select * from `COLUMNS` c where c.TABLE_SCHEMA='" + modelSchema + "' and c.TABLE_NAME='" + tableName + "' ";
        ResultSet set = connection.createStatement().executeQuery(sqlStr);
        while (set.next()) {
            Property property = new Property();
            String col_name = set.getString("COLUMN_NAME");
            String data_type = set.getString("DATA_TYPE");
            String col_key = set.getString("COLUMN_KEY");
            String col_comment = set.getString("COLUMN_COMMENT");

            property.setPropertyName(TableNameConvertUtil.convert4ProName(col_name));
            property.setClazzType(DataTypeAdaptUtil.match(data_type));
            property.setDescription(col_comment);
            property.setColumnName(col_name);
            property.setKey(col_key.equals("PRI") ? true : false);
            model.addProperty(property);
            if (col_key.equals("PRI")) {
                model.setKeyProperty(property);
            }
        }
        set.close();
        String sql2 = "SELECT TABLE_COMMENT from `TABLES` ts where ts.TABLE_SCHEMA='" + modelSchema + "' and ts.TABLE_NAME='" + tableName + "'";
        ResultSet commentSet = connection.createStatement().executeQuery(sql2);
        commentSet.next();
        String tab_comment = commentSet.getString("TABLE_COMMENT");
        model.setDescription(tab_comment);
        commentSet.close();
        connection.close();
        return model;
    }

    /**
     * 获取包名
     * @param model
     * @return
     */
    private static List<String> getPackageName(Model model) {
        List<String> pnames = new ArrayList<String>();
        for (Property property : model.getProperties()) {
            try {
                String packageName = property.getClazzType().getPackage().getName();
                if(!pnames.contains(packageName) && !packageName.equals("java.lang")) {
                    pnames.add(packageName);
                }
            } catch (Exception e) {
                System.out.println(property.getColumnName());
                System.out.println(property.getClazzType());
            }

        }
        return pnames;
    }

    private static void putConsts(Map root, Model model) {
        root.put("xxx", NameConvertUtil.convert2LowerHeadName(model.getName()));
        root.put("XxxDao", model.getName()+"Dao");
        root.put("xxxDao", NameConvertUtil.convert2LowerHeadName(model.getName())+"Dao");
        root.put("XxxDaoImpl", model.getName()+"DaoImpl");
        root.put("controller", model.getName()+"Controller");
        root.put("controllerPath",NameConvertUtil.convert2LowerName(model.getName()));
        root.put("XxxBean", model.getName()+"Bean");
        root.put("xxxBean", NameConvertUtil.convert2LowerHeadName(model.getName())+"Bean");
        root.put("Id", NameConvertUtil.convert2UpperHeadName(model.getKeyProperty().getPropertyName()));
        root.put("id", model.getKeyProperty().getPropertyName());
        root.put("id_col", model.getKeyProperty().getColumnName());
        root.put("xxxService", NameConvertUtil.convert2LowerHeadName(model.getName())+"Service");
        root.put("XxxService", model.getName()+"Service");
        root.put("XxxServiceImpl", model.getName()+"ServiceImpl");
        root.put("keyType", DataTypeAdaptUtil.convert(model.getKeyProperty().getClazzType()));
        root.put("id_col", model.getKeyProperty().getColumnName());
    }

    private static void createBean(Configuration cfg,Map root)throws Exception{
        Template t = cfg.getTemplate("model_bean.ftl");
        String filePath = Constant.outPutRootPath+TableNameConvertUtil.convert4ClassName(tableName)+"Bean.java";
        PrintUtil.println(filePath);
        File file = new File(filePath);
        file.createNewFile();
        FileWriter fileWriter = new FileWriter(file);
        Environment ev = t.createProcessingEnvironment(root, fileWriter, null);
        ev.process();
    }

    private static void createDao(Configuration cfg,Map root)throws Exception{
        Template t = cfg.getTemplate("dao_impl.ftl");
        String filePath = Constant.outPutRootPath+TableNameConvertUtil.convert4ClassName(tableName)+"DaoImpl.java";
        PrintUtil.println(filePath);
        File file = new File(filePath);
        file.createNewFile();
        FileWriter fileWriter = new FileWriter(file);
        Environment ev = t.createProcessingEnvironment(root, fileWriter, null);
        ev.process();
    }

    private static void createService(Configuration cfg,Map root)throws Exception{
        Template t = cfg.getTemplate("service_impl.ftl");
        String filePath = Constant.outPutRootPath+TableNameConvertUtil.convert4ClassName(tableName)+"ServiceImpl.java";
        PrintUtil.println(filePath);
        File file = new File(filePath);
        file.createNewFile();
        FileWriter fileWriter = new FileWriter(file);
        Environment ev = t.createProcessingEnvironment(root, fileWriter, null);
        ev.process();
    }

    private static void createController(Configuration cfg,Map root)throws Exception{
        Template t = cfg.getTemplate("controller.ftl");
        String filePath = Constant.outPutRootPath+TableNameConvertUtil.convert4ClassName(tableName)+"Controller.java";
        PrintUtil.println(filePath);
        File file = new File(filePath);
        file.createNewFile();
        FileWriter fileWriter = new FileWriter(file);
        Environment ev = t.createProcessingEnvironment(root, fileWriter, null);
        ev.process();
    }


    private static void createXML(Configuration cfg,Map root)throws Exception{
        Template t = cfg.getTemplate("sql_mapper.ftl");
        String filePath = Constant.outPutRootPath+TableNameConvertUtil.convert4ClassName(tableName)+".xml";
        PrintUtil.println(filePath);
        File file = new File(filePath);
        file.createNewFile();
        FileWriter fileWriter = new FileWriter(file);
        Environment ev = t.createProcessingEnvironment(root, fileWriter, null);
        ev.process();
    }

    private static void createVM(Configuration cfg,Map root)throws Exception{
        Template t = cfg.getTemplate("vm.ftl");
        String filePath = Constant.outPutRootPath+"index.vm";
        PrintUtil.println(filePath);
        File file = new File(filePath);
        file.createNewFile();
        FileWriter fileWriter = new FileWriter(file);
        Environment ev = t.createProcessingEnvironment(root, fileWriter, null);
        ev.process();
    }


    private static List<Property> getSearchPros(Model model, List<String> searchProsNames) {
        List<Property> result = new ArrayList<Property>();
        for (String searchProsName : searchProsNames) {
            for (Property property : model.getProperties()) {
                if(property.getColumnName().equals(searchProsName)) {
                    result.add(property);
                }
            }
        }
        return result;
    }

    public static void main(String ... args)throws Exception{
        autoCreateBeanServiceDaoXml();
    }
}
